#pragma once
#include"Sem.hpp"
#include"Lock.hpp"
#include<vector>
//基于信号量的多生产多消费模型
template<class T>
class RunQuenue
{
    public:
    RunQuenue(int n):cap(n),block_p(n),full_c(0),c_step(0),p_step(0)
    {
        queue.resize(n);
    }
    ~RunQuenue()
    {
    }
    //生产行为
    void Enqueue(const T data)
    {
        product_m.lock();
        block_p.p();
        queue[p_step++]=data;
        //维持环形
        p_step%=cap;
        full_c.V();
        product_m.unlock();
    }
    void Popqueue(T* out)
    {
        consum_m.lock();
        full_c.P();
        *out=queue[c_step++];
        c_step%=cap;
        block_p.V();
        consum_m.unlock();
    }
    private:
    std::vector<T> queue;
    //环形队列容量
    int cap;

    Sem block_p;
    Sem full_c;

    Mutex product_m;
    Mutex consum_m;

    int p_step;
    int c_step;
};